package com.d2rv.skybox;

import com.d2rv.offscreen.OffScreen3D;
import com.d2rv.settings.Settings;
import java.io.File;
import processing.core.PApplet;
import processing.core.PImage;
import processing.core.PVector;

/**
 * This class creates a skybox
 *
 * @author Darrieutort A., Dupouy A., Rossignol L., Van Poucke A.
 */
public class Skybox {

    PImage tex1, tex2, tex3, tex4, tex5, tex6;

    /**
     * Default constructor.
     *
     * @param parent
     */
    public Skybox(PApplet parent) {
        loadCurrentSkybox(parent);
    }

    /**
     * Loads the six pictures for the skybox.
     *
     * @param parent
     */
    private void loadCurrentSkybox(PApplet parent) {
        try {
            String ext = ".jpg";
            tex1 = parent.loadImage(parent.dataPath("models" + File.separator + "skybox" + File.separator + "front" + ext));
            tex2 = parent.loadImage(parent.dataPath("models" + File.separator + "skybox" + File.separator + "back" + ext));
            tex3 = parent.loadImage(parent.dataPath("models" + File.separator + "skybox" + File.separator + "left" + ext));
            tex4 = parent.loadImage(parent.dataPath("models" + File.separator + "skybox" + File.separator + "right" + ext));
            tex5 = parent.loadImage(parent.dataPath("models" + File.separator + "skybox" + File.separator + "bottom" + ext));
            tex6 = parent.loadImage(parent.dataPath("models" + File.separator + "skybox" + File.separator + "top" + ext));

        } catch (Exception ex) {
            System.err.println("Unexpected error while loading pictures skybox");
        }
    }

    /**
     * Creates a textured cube.
     *
     * @param parent
     */
    private void TexturedCube(OffScreen3D parent) {
        float p = Settings.getInstance().skyboxhalfsize();
        float m = -p;

        PVector P000 = new PVector(m, m, m);
        PVector P010 = new PVector(m, p, m);
        PVector P110 = new PVector(p, p, m);
        PVector P100 = new PVector(p, m, m);
        PVector P001 = new PVector(m, m, p);
        PVector P011 = new PVector(m, p, p);
        PVector P111 = new PVector(p, p, p);
        PVector P101 = new PVector(p, m, p);

        TexturedCubeSide(parent, P100, P000, P010, P110, tex1);   // -Z "Front" face
        TexturedCubeSide(parent, P001, P101, P111, P011, tex2);   // +Z "Back" face
        TexturedCubeSide(parent, P000, P001, P011, P010, tex3);   // -X "Left" face
        TexturedCubeSide(parent, P101, P100, P110, P111, tex4);   // +X "Right" face
        TexturedCubeSide(parent, P110, P010, P011, P111, tex5);   // +Y "Base" face
        TexturedCubeSide(parent, P101, P001, P000, P100, tex6);   // -Y "Top" face
    }

    /**
     * Creates a textured face.
     *
     * @param parent current offscreen
     * @param P1 first corner
     * @param P2 second corner
     * @param P3 third corner
     * @param P4 fourth corner
     * @param tex texture to apply
     */
    private void TexturedCubeSide(OffScreen3D parent, PVector P1, PVector P2, PVector P3, PVector P4, PImage tex) {
        parent.beginShape(OffScreen3D.QUADS);
        if (tex == null) {
            return;
        }
        parent.texture(tex);
        parent.vertex(P1.x, P1.y, P1.z, 1, 0);
        parent.vertex(P2.x, P2.y, P2.z, 0, 0);
        parent.vertex(P3.x, P3.y, P3.z, 0, 1);
        parent.vertex(P4.x, P4.y, P4.z, 1, 1);
        parent.endShape();
    }

    /**
     * Draws the skybox (the textured cube).
     *
     * @param parent the current offscreen
     */
    public void draw(OffScreen3D parent) {
        parent.noStroke();
        parent.pushMatrix();
        parent.rotateX((float) Math.toRadians(180)); // pour éviter d'avoir a rotater les textures
        parent.textureMode(OffScreen3D.NORMAL);
        TexturedCube(parent);
        parent.popMatrix();
    }
}